package br.requisiteworks.requisito.modelo.dao.jpa;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import javax.persistence.TypedQuery;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import br.requisiteworks.requisito.modelo.AtributoRequisito;
import br.requisiteworks.requisito.modelo.AtributoTipoRequisito;
import br.requisiteworks.requisito.modelo.Requisito;
import br.requisiteworks.requisito.modelo.TipoRequisito;
import br.requisiteworks.requisito.modelo.dao.AtributoRequisitoDao;
import br.requisiteworks.util.persistencia.ErroBancoDados;
import br.requisiteworks.util.persistencia.ResultadoVazio;

@Repository
public class JpaAtributoRequisitoDao implements AtributoRequisitoDao {

	@PersistenceContext
	private EntityManager em;

	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void insert(AtributoRequisito atributo) throws ErroBancoDados {
		try {
			em.persist(atributo);
		} catch (PersistenceException e) {
			throw new ErroBancoDados(
					"Ocorreu um erro ao adicionar atributo de requisito: "
							+ atributo, e);
		}
	}

	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void update(AtributoRequisito requsito) {
		em.merge(requsito);
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public void delete(AtributoRequisito requsito) {
		requsito.setRegistroAtivo(false);
		em.remove(requsito);
	}

	@Override
	public AtributoRequisito select(int numero) throws ResultadoVazio {
		AtributoRequisito reference = em.find(AtributoRequisito.class, numero);

		if (reference == null) {
			throw new ResultadoVazio(
					"Nao foi encontrado tipo de requisito de numero = "
							+ numero);
		}
		return reference;
	}

	@Override
	public List<AtributoRequisito> select(AtributoTipoRequisito atributoTipo)
			throws ResultadoVazio {
		TypedQuery<AtributoRequisito> query = em
				.createQuery(
						"SELECT DISTINCT OBJECT(a) FROM AtributoRequisito a WHERE a.tipo=:tipo",
						AtributoRequisito.class);
		query.setParameter("tipo", atributoTipo);
		List<AtributoRequisito> resultado = query.getResultList();

		if (resultado == null || resultado.isEmpty()) {
			throw new ResultadoVazio(
					"Nao foi encontrado tipo de requisito com nome = "
							+ atributoTipo);
		}

		return resultado;
	}

	@Override
	public List<AtributoRequisito> select() throws ResultadoVazio {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public AtributoRequisito select(int numero, int versao)
			throws ResultadoVazio {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<AtributoRequisito> select(TipoRequisito tipo)
			throws ResultadoVazio {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<AtributoRequisito> select(Requisito requisito)
			throws ResultadoVazio {
		// TODO Auto-generated method stub
		return null;
	}

	/*
	 * @Override public List<TipoRequisito> select() throws ResultadoVazio {
	 * TypedQuery<TipoRequisito> query = em .createQuery(
	 * "SELECT DISTINCT OBJECT(f) FROM Funcionario f WHERE f.registroAtivo=true"
	 * , TipoRequisito.class); List<TipoRequisito> resultado =
	 * query.getResultList();
	 * 
	 * if (resultado == null || resultado.isEmpty()) { throw new ResultadoVazio(
	 * "Nao foi encontrado nenum registro de funcionario ativo"); }
	 * 
	 * return resultado; }
	 */

}
